package mqtt

import (
	"bytes"
	"gitee.com/squbirreland/imgo"
	logger2 "gitee.com/squbirreland/imgo/utils/logger"
	"log"
	"time"
)

var logger = logger2.NewLoggerFactory(false, "").GetLogger()

// mqttIWorkRoutine 默认实现
type mqttIWorkRoutine struct {
	monitorDelay int64
	log          bool
}

// NewMqttIWorkRoutine 默认实现的构造方法
func NewMqttIWorkRoutine(monitorDelay int64, log bool) *mqttIWorkRoutine {
	return &mqttIWorkRoutine{monitorDelay: monitorDelay, log: log}
}

//ReadListener 实现接口 并注意捕获异常以避免影响主程序
func (d *mqttIWorkRoutine) ReadListener(worker *imgo.WorkRoutine) {
	defer func() {
		err := recover()
		if err != nil {
			log.Println(" -- default read listener throw err : ", err)
		}
	}()
	for {
		if worker.Conn == nil {
			break
		}
		data := make([]byte, 256, 256)
		//read
		worker.ConnLocker.Lock()
		read, err := (*worker.Conn).Read(data)
		worker.ConnLocker.Unlock()
		if err != nil {
			worker.Exit <- worker.Conn
			break
		}
		data = data[:read]
		if d.log {
			logger.Info().Printf(" <<< from %s -- packet : %x\n%s\n", (*worker.Conn).RemoteAddr(), data, bytes.NewBuffer(data).String())
		}
		worker.ChanIn <- &data
		time.Sleep(time.Duration(d.monitorDelay))
	}
}

// WriteLooper 实现的写入方法
func (d *mqttIWorkRoutine) WriteLooper(worker *imgo.WorkRoutine) {
	defer func() {
		err := recover()
		if err != nil {
			log.Println(" -- default write looper throw err : ", err)
		}
	}()
	for {
		if worker.Conn == nil {
			break
		}
		if b, ok := <-worker.ChanOut; ok {
			//write
			worker.ConnLocker.Lock()
			write, err := (*worker.Conn).Write(*b)
			worker.ConnLocker.Unlock()
			if err != nil || write != len(*b) {
				worker.Exit <- worker.Conn
				break
			}
			if d.log {
				logger.Info().Printf(" >>> to %s packet : %x \n", (*worker.Conn).RemoteAddr(), *b)
			}
		}
	}
}

// Copy 实现的复制方法
func (d *mqttIWorkRoutine) Copy() imgo.IWorkRoutine {
	dd := mqttIWorkRoutine{
		monitorDelay: d.monitorDelay,
		log:          d.log,
	}
	return &dd
}
